package com.xh.pmo.db;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import com.xh.pmo.util.SqlHeper;

public class Session {
	
	private Connection conn = null;
	private PreparedStatement pstmt=null;
	private ResultSet rs=null;
	
	public Session(Connection conn) {
		this.conn = conn;
	}
	
	
	
	public void save(Object obj) {
	try {
		conn.setAutoCommit(false);
		
		
		Field f = obj.getClass().getDeclaredField("id");
		
		f.setAccessible(true);
		f.set(obj, getMaxId(obj));
		
		SqlHeper sql = new SqlHeper();
		sql.addInsertCondition(obj);
		System.out.println(sql.getInsertClause());
		pstmt =  conn.prepareStatement(sql.getInsertClause()); 
		List<Object> objects = sql.getParameters();
		if(objects != null && objects.size() > 0) {
			for(int i=0; i<objects.size(); i++) {
				pstmt.setObject(i + 1,objects.get(i));
			}
		}
		pstmt.executeUpdate();
		conn.commit();
	} catch (Exception e) {
		try {
			conn.rollback();
			conn.setAutoCommit(true);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
		e.printStackTrace();
	} 
	
}

	public void delete(Long id ,Class clazz) {
		String sql = "DELETE FROM " + clazz.getSimpleName() + " WHERE id = " + id;
		try {
			conn.setAutoCommit(false);
			pstmt = conn.prepareStatement(sql);
			pstmt.executeUpdate();
			conn.commit();
		} catch (Exception e) {
			try {
				conn.rollback();
				conn.setAutoCommit(true);
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} 
	}
	
	private Long getMaxId(Object obj) throws SQLException{
		
		String sql = "SELECT MAX(id) + 1 FROM " + obj.getClass().getSimpleName();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			rs.next();
			Long maxId = rs.getLong(1);
			if(maxId == null || maxId == 0L) {
				maxId =  1L;
			}
			
			System.out.println(maxId);
			conn.commit();
		return maxId;
	}
	
	public void update(Object entity) {
		try {
			conn.setAutoCommit(false);
			SqlHeper sql = new SqlHeper();
			sql.addUpdateCondition(entity);
			
			System.out.println(sql.getUpdateClause());
			pstmt = conn.prepareStatement(sql.getUpdateClause());
			
			List<Object> objects = sql.getParameters();
			if(objects != null && objects.size() > 0) {
				for(int i=0; i<objects.size(); i++) {
					pstmt.setObject(i + 1,objects.get(i));
				}
			}
			
			pstmt.executeUpdate();
			conn.commit();
		} catch (Exception e) {
			try {
				conn.rollback();
				conn.setAutoCommit(true);
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}
	
	public Query createQuery (String sql) {
		Query query = new Query(conn, sql);
		return query;
	}
	
	public Object get(Long id, Class clazz) {
		String sql = "SELECT * FROM " + clazz.getSimpleName() + " WHERE id="+id;
		Object obj = null;
		return createQuery(sql).uniqueResult(clazz);
	}
	
	public  void closeSession() {
		if(pstmt != null) {
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			pstmt = null;
		}
		if(conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = null;
		}
	}
	
	
	public Connection getConn() {
		return conn;
	}

	public void setConn(Connection conn) {
		this.conn = conn;
	}

	public PreparedStatement getPstmt() {
		return pstmt;
	}

	public void setPstmt(PreparedStatement pstmt) {
		this.pstmt = pstmt;
	}

	public ResultSet getRs() {
		return rs;
	}

	public void setRs(ResultSet rs) {
		this.rs = rs;
	}

	
	

	
}
